package webgamemaker.RPGMakerVXLoader;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;

import com.google.gwt.xhr.client.ReadyStateChangeHandler;
import com.google.gwt.xhr.client.XMLHttpRequest;
import webgamemaker.Common.Callback;
import webgamemaker.Common.GameMap;
import webgamemaker.Common.MapData;
import webgamemaker.Common.Tile;
import webgamemaker.Common.TileData;
import webgamemaker.Common.TileSet;
import webgamemaker.Common.TileSetGroup;
import webgamemaker.RPGMakerVXLoader.Marshal.MarshalValueObject;
import webgamemaker.RPGMakerVXLoader.Marshal.MarshalValueUserDef;

public class RPGMakerVXLoader 
{
	public String filename;
	public MapData mapData;
	public TileSetGroup tilesetA;
	public TileSet tilesetA1, tilesetA2, tilesetA3, tilesetA4, tilesetA5;
	public TileSet tilesetB, tilesetC, tilesetD, tilesetE;
	public TileData listeTile[][];
	public boolean loaded;
	public ArrayList<Callback> listCallback;
	
	public native void overrideMimeType(XMLHttpRequest req, String val)/*-{
		req.overrideMimeType(val);
	}-*/;
	
	public void fillTile(int index, int id, int num, TileData tile)
	{
		for(int i=0;i<num; i++)
		{
			listeTile[id][index] = tile;
			id++;
			if(id==256)
			{
				id = 0;
				index++;
			}
		}
	}
	
	public void addLoadCallback(Callback loadCallback)
	{
		if(loaded)
			loadCallback.onCall(this);
		else listCallback.add(loadCallback);
	}
	
	class LoadCallback implements Callback
	{
		public void onCall(Object src) 
		{
			System.out.println("load"+tilesetA1.loaded+tilesetA2.loaded+tilesetA3.loaded+tilesetA4.loaded+tilesetA5.loaded+tilesetB.loaded+tilesetC.loaded+tilesetD.loaded+tilesetE.loaded);
			if(tilesetA1.loaded && tilesetA2.loaded && tilesetA3.loaded && tilesetA4.loaded && tilesetA5.loaded
					&& tilesetB.loaded && tilesetC.loaded && tilesetD.loaded && tilesetE.loaded
					)
			{
				tilesetA.addTileSet(tilesetA1);
				tilesetA.addTileSet(tilesetA2);
				tilesetA.addTileSet(tilesetA3);
				tilesetA.addTileSet(tilesetA4);
				tilesetA.addTileSet(tilesetA5);
				for(int i = 0; i < 256; i++)
					fillTile(0,i,1,tilesetB.tiles.get(i));
				for(int i = 0; i < 256; i++)
					fillTile(1,i,1,tilesetC.tiles.get(i));
				for(int i = 0; i < 256; i++)
					fillTile(2,i,1,tilesetD.tiles.get(i));
				for(int i = 0; i < 256; i++)
					fillTile(3,i,1,tilesetE.tiles.get(i));
				for(int i = 0; i < 128; i++)
					fillTile(6,i,1,tilesetA5.tiles.get(i));
				for(int i = 0; i < 16; i++)
					fillTile(8+(i*48)/256,(i*48)%256,47,tilesetA1.tiles.get(i));
				for(int i = 0; i < 32; i++)
					fillTile(11+(i*48)/256,(i*48)%256,47,tilesetA2.tiles.get(i));
				for(int i = 0; i < 32; i++)
					fillTile(17+(i*48)/256,(i*48)%256,16,tilesetA3.tiles.get(i));
				for(int i = 0; i < 3; i++)
					for(int j = 0; j < 8; j++)
					{
						fillTile(23+3*i+(j*48)/256,(j*48)%256,47,tilesetA4.tiles.get(i*16+j));
						fillTile(24+3*i+(127+j*48)/256,(127+j*48)%256,16,tilesetA4.tiles.get(i*16+8+j));
					}
				XMLHttpRequest req = XMLHttpRequest.create();
			    req.open("GET", filename);
			    overrideMimeType(req,"text/plain; charset=x-user-defined");
			    req.setRequestHeader("Pragma", "no-cache");
			    //req.setRequestHeader("Content-type", "text/plain; charset=x-user-defined");
			    req.setOnReadyStateChange(new ChangeHandler());
			    req.send();
			}
		}
		
	}
	class ChangeHandler implements ReadyStateChangeHandler
	{
		public ChangeHandler()
		{
		}
		public void onReadyStateChange(XMLHttpRequest xhr){
			if(xhr.getReadyState() == 4)
			{
				int size = xhr.getResponseText().length();
				byte array[] = new byte[size];
				for(int i=0;i<size;i++)
					array[i] = (byte)getCharCode(xhr,i);
				try {
					MarshalValueObject root = (MarshalValueObject)Marshal.decode(array);
					MarshalValueObject BGM = (MarshalValueObject)((MarshalValueObject)root).get_value("@bgm");
					Iterator<String> it = root.value.keySet().iterator();
					while(it.hasNext())
						System.out.println(it.next());
					MarshalValueUserDef table = (MarshalValueUserDef)root.get_value("@data");
					/*System.out.print("0 : ");
					for(int i=0;i<table.value.size();i++)
					{
						System.out.print((((int)table.get_value(i))&255)+" ");
						if(i%100 == 74)
							System.out.print("\n"+(i+1)+" : ");
					}*/
					Object tab[] = table.value.toArray();
					int width = ((Byte)tab[4]&255) | ((Byte)tab[5]&255)<<8 | ((Byte)tab[6]&255)<<16 | ((Byte)tab[7]&255)<<24; 
					int height = ((Byte)tab[8]&255) | ((Byte)tab[9]&255)<<8 | ((Byte)tab[10]&255)<<16 | ((Byte)tab[11]&255)<<24; 
					int num_layer = ((Byte)tab[12]&255) | ((Byte)tab[13]&255)<<8 | ((Byte)tab[14]&255)<<16 | ((Byte)tab[15]&255)<<24;
					mapData = new MapData(width, height, num_layer);
					for(int j=0; j<height; j++)
					{
						for(int i=0; i<width; i++)
						{
							int id1 = 20+i*2+j*2*width;
							int id2 = id1+2*width*height;
							int id3 = id2+2*width*height;
							mapData.tiles[i+j*width][0] = listeTile[((Byte)tab[id1]&255)][((Byte)tab[id1+1]&255)];
							mapData.tiles[i+j*width][1] = listeTile[((Byte)tab[id2]&255)][((Byte)tab[id2+1]&255)];
							mapData.tiles[i+j*width][2] = listeTile[((Byte)tab[id3]&255)][((Byte)tab[id3+1]&255)];
						}
					}
					mapData.addTileSet(tilesetA);
					mapData.addTileSet(tilesetB);
					mapData.addTileSet(tilesetC);
					mapData.addTileSet(tilesetD);
					mapData.addTileSet(tilesetE);
					
					loaded = true;
					for(Callback callback : listCallback)
						callback.onCall(RPGMakerVXLoader.this);
					listCallback.clear();
				} catch (Marshal.MarshalException e) {
					e.printStackTrace();
				}
			}
		}
		
		public native int getCharCode(XMLHttpRequest xhr, int id)/*-{
			return xhr.responseText.charCodeAt(id) & 0xff;
		}-*/;
	}
	
	public RPGMakerVXLoader(String filename)
	{
		this.filename = filename;
		listCallback = new ArrayList<Callback>();
		listeTile = new TileData[256][32];
		LoadCallback loadCallback = new LoadCallback();
		tilesetA = new TileSetGroup(32,32);
		tilesetA1 = new TileSetA1("../data/TileA1.png");
		tilesetA2 = new TileSetA2("../data/TileA2.png");
		tilesetA3 = new TileSetA3("../data/TileA3.png");
		tilesetA4 = new TileSetA4("../data/TileA4.png");
		tilesetA5 = new TileSet("../data/TileA5.png",32,32);
		tilesetB = new TileSetB("../data/TileB.png");
		tilesetC = new TileSetB("../data/TileC.png");
		tilesetD = new TileSetB("../data/TileD.png");
		tilesetE = new TileSetB("../data/TileE.png");
		tilesetA1.addLoadCallback(loadCallback);
		tilesetA2.addLoadCallback(loadCallback);
		tilesetA3.addLoadCallback(loadCallback);
		tilesetA4.addLoadCallback(loadCallback);
		tilesetA5.addLoadCallback(loadCallback);
		tilesetB.addLoadCallback(loadCallback);
		tilesetC.addLoadCallback(loadCallback);
		tilesetD.addLoadCallback(loadCallback);
		tilesetE.addLoadCallback(loadCallback);
		tilesetA.name = "A";
		tilesetB.name = "B";
		tilesetC.name = "C";
		tilesetD.name = "D";
		tilesetE.name = "E";
	}
	
}
